/**
 * ProxyManager.java
 * 2007-12-4 ����05:48:45
 * Author: Lex
 * Note:
 */
package lex.proxyverfier;

import java.net.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import org.lex.net.proxy.ProxyServer;


public class ProxyTableModel extends AbstractTableModel
{
	private static final int DEFAULT_PROXY_COUNT = 4;
	private static final String[] COLUMN_NAMES = { "#", "Name", "Type", "Host", "Port", "Result" };
	private static final int RESULT_COLUMN = COLUMN_NAMES.length - 1;
	// ===============================================
	private ArrayList<ProxyServer2> proxies = null;

	public ProxyTableModel()
	{
		super();
		this.proxies = new ArrayList<ProxyServer2>( DEFAULT_PROXY_COUNT );
	}

	public static String[] getCanFilteredColumnNames()
	{
		return Arrays.copyOfRange( COLUMN_NAMES, 1, COLUMN_NAMES.length - 1 );
	}

	public void fireVerifyResultUpdated( String name )
	{
		for( int i = 0; i < proxies.size(); i++ )
			if( proxies.get( i ).getName().equals( name ) )
			{
				this.fireTableCellUpdated( i, RESULT_COLUMN );
				return;
			}
	}

	public void put( ProxyServer ps )
	{
		if( null == ps )
			return;
		this.put( ps.getName(), ps.getType(), ps.getHost(), ps.getPort() );
	}

	public void put( String name, Proxy.Type type, String host, int port )
	{
		if( null == name || null == host || "".equals( host ) )
			throw new NullPointerException( "Name or Server could not be null" );
		if( "".equals( name ) || ProxyServer.DIRECT.getName().equals( name ) )
		{
			return;
		}
		// ==================================
		ProxyServer2 ps = null;
		int row = this.indexOf( name );
		if( -1 == row )
		{
			ps = new ProxyServer2( name, type, host, port );
			proxies.add( ps );
			row = proxies.size() - 1;
		}
		else
			ps = proxies.get( row );
		ps = new ProxyServer2( ps.getName(), type, host, port );
		proxies.set( row, ps );
		this.fireTableDataChanged();
	}

	public void remove( int row )
	{
		this.proxies.remove( row );
		this.fireTableDataChanged();
	}

	public void remove( String name )
	{
		if( null == name || "".equals( name ) )
			throw new NullPointerException( "Proxy name could not be null" );
		int row = this.indexOf( name );
		if( -1 != row )
		{
			proxies.remove( row );
			this.fireTableDataChanged();
		}
	}

	public void clear()
	{
		this.proxies.clear();
		this.fireTableDataChanged();
	}

	public ProxyServer2 getProxyServer( int row )
	{
		return this.proxies.get( row );
	}

	public ProxyServer2[] getAllProxyServers()
	{
		return this.proxies.toArray( new ProxyServer2[this.proxies.size()] );
	}
	
	public List<ProxyServer> getProxyServerList()
	{
		List<ProxyServer> list = new ArrayList<ProxyServer>(proxies.size());
		list.addAll( this.proxies );
		return list;
	}

	public ProxyServer2[] getSelectedProxyServers()
	{
		ArrayList<ProxyServer2> tmp = new ArrayList<ProxyServer2>();
		for( ProxyServer2 p : proxies )
			if( p.isSelected() )
				tmp.add( p );
		return tmp.toArray( new ProxyServer2[tmp.size()] );
	}

	private int indexOf( String name )
	{
		if( null == name || 0 == name.length() )
			throw new NullPointerException( "Proxy name could not be null" );
		int count = proxies.size();
		for( int i = 0; i < count; i++ )
		{
			ProxyServer2 p = proxies.get( i );
			if( p.getName().equals( name ) )
				return i;
		}
		return -1;
	}

	@Override
	public boolean isCellEditable( int row, int column )
	{
		return column == 0;
	}

	@Override
	public void setValueAt( Object value, int row, int column )
	{
		if( column != 0 )
			return;
		proxies.get( row ).setSelected( (Boolean) value );
		this.fireTableCellUpdated( row, column );
	}

	@Override
	public int getColumnCount()
	{
		return COLUMN_NAMES.length;
	}

	@Override
	public int getRowCount()
	{
		return proxies.size();
	}

	@Override
	public String getColumnName( int column )
	{
		return COLUMN_NAMES[column];
	}

	@Override
	public Class<?> getColumnClass( int column )
	{
		switch( column )
		{
		case 0:
			return Boolean.class;
		case 1:
			return String.class;
		case 2:
			return Proxy.class;
		case 3:
			return String.class;
		case 4:
			return Integer.class;
		default:
			return Object.class;
		}
	}

	@Override
	public Object getValueAt( int row, int column )
	{
		if( row >= proxies.size() )
			return null;
		ProxyServer2 ps = this.proxies.get( row );
		switch( column )
		{
		case 0:
			return ps.isSelected();
		case 1:
			return ps.getName();
		case 2:
			return ps.getType();
		case 3:
			return ps.getHost();
		case 4:
			return ps.getPort();
		case 5:
			return ps.getVerifyResult();
		default:
			return null;
		}
	}
}
